<template>
  <el-tree
    class="axiom-tree"
    ref="treeRef"
    :data="data"
    :props="props"
    :show-checkbox="showCheckbox"
    :node-key="nodeKey"
    :default-expanded-keys="defaultExpandedKeys"
    :default-checked-keys="defaultCheckedKeys"
    :filter-node-method="filterNodeMethod"
    @node-click="(data, node, component) => $emit('node-click', data, node, component)"
    @check-change="(data, checked, indeterminate) => $emit('check-change', data, checked, indeterminate)"
    @node-expand="(data, node, component) => $emit('node-expand', data, node, component)"
    @node-collapse="(data, node, component) => $emit('node-collapse', data, node, component)"
    v-bind="$attrs"
  >
    <!-- [新增] 空状态插槽 -->
    <template #empty>
      <slot name="empty">
        <AxiomEmpty />
      </slot>
    </template>

    <template #default="{ data }">
      <div
        class="axiom-tree-node"
        @mouseenter="showActions && (hoveredNodeId = data[nodeKey])"
        @mouseleave="showActions && (hoveredNodeId = null)"
      >
        <AxiomInput
          v-if="editable && editingNodeId === data[nodeKey]"
          v-model="editingNodeName"
          @blur="cancelEdit"
          @keydown.enter.prevent="finishEdit(data)"
          @keydown.esc.prevent="cancelEdit"
          autofocus
          size="small"
          class="axiom-tree__input"
        />
        <span v-else class="axiom-tree__label">{{ data[props.props.label] }}</span>

        <AxiomDropdown
          :style="{ visibility: showActions && hoveredNodeId === data[nodeKey] && editingNodeId !== data[nodeKey] ? 'visible' : 'hidden' }"
          @command="handleActionCommand($event, data)"
          @click.stop
        >
          <AxiomButton icon="more-filled" text circle size="small" />
          <template #dropdown>
            <AxiomDropdownMenu>
              <AxiomDropdownItem
                v-for="item in actionMenuItems"
                :key="item.command"
                :command="item.command"
                :icon="item.icon"
                :divided="item.divided"
              >
                {{ item.label }}
              </AxiomDropdownItem>
            </AxiomDropdownMenu>
          </template>
        </AxiomDropdown>
      </div>
    </template>
  </el-tree>
</template>

<script setup>
import { ref } from 'vue';
import AxiomEmpty from './AxiomEmpty.vue';
import AxiomInput from './AxiomInput.vue';
import AxiomDropdown from './AxiomDropdown.vue';
import AxiomDropdownMenu from './AxiomDropdownMenu.vue';
import AxiomDropdownItem from './AxiomDropdownItem.vue';
import AxiomButton from './AxiomButton.vue';

defineOptions({
  name: 'AxiomTree'
});

const props = defineProps({
  data: { type: Array, default: () => [] },
  props: { type: Object, default: () => ({ label: 'label', children: 'children' }) },
  showCheckbox: { type: Boolean, default: false },
  nodeKey: { type: String, required: true },
  defaultExpandedKeys: { type: Array, default: () => [] },
  defaultCheckedKeys: { type: Array, default: () => [] },
  filterNodeMethod: { type: Function, default: null },
  showActions: { type: Boolean, default: false },
  actionMenuItems: { type: Array, default: () => [] },
  editable: { type: Boolean, default: true },
});

const emit = defineEmits(['node-click', 'check-change', 'action-command', 'node-renamed', 'node-expand', 'node-collapse']);

const treeRef = ref(null);
const hoveredNodeId = ref(null);
const editingNodeId = ref(null);
const editingNodeName = ref('');
const originalNodeName = ref('');

function handleActionCommand(command, nodeData) {
  if (command === 'rename' && props.editable) {
    startEdit(nodeData);
  } else {
    emit('action-command', command, nodeData);
  }
}

function startEdit(nodeData) {
  editingNodeId.value = nodeData[props.nodeKey];
  editingNodeName.value = nodeData[props.props.label];
  originalNodeName.value = nodeData[props.props.label];
}

async function finishEdit(nodeData) {
  if (editingNodeName.value && editingNodeName.value !== originalNodeName.value) {
    emit('node-renamed', {
      nodeId: nodeData[props.nodeKey],
      newName: editingNodeName.value,
      nodeData: nodeData
    });
  }
  cancelEdit();
}

function cancelEdit() {
  editingNodeId.value = null;
  editingNodeName.value = '';
  originalNodeName.value = '';
}

const filter = (value) => {
  treeRef.value?.filter(value);
};

const getCheckedKeys = () => {
  return treeRef.value?.getCheckedKeys();
};

const setCheckedKeys = (keys) => {
  treeRef.value?.setCheckedKeys(keys);
};

const getHalfCheckedKeys = () => {
  return treeRef.value?.getHalfCheckedKeys() || [];
};

defineExpose({ filter, getCheckedKeys, setCheckedKeys, getHalfCheckedKeys, treeRef });
</script>

<style lang="scss">
.axiom-tree-node {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  flex: 1;
  padding-right: 4px; // Give some space for the dropdown
}

.axiom-tree__label {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding-right: 8px;
}

.axiom-tree__input .el-input__inner {
  height: 24px;
}
</style> 